// Generated from code/ch16/Cymbol.g by ANTLR 4.9.0-SNAPSHOT


import { ATN } from "antlr4ts/atn/ATN";
import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer";
import { FailedPredicateException } from "antlr4ts/FailedPredicateException";
import { NotNull } from "antlr4ts/Decorators";
import { NoViableAltException } from "antlr4ts/NoViableAltException";
import { Override } from "antlr4ts/Decorators";
import { Parser } from "antlr4ts/Parser";
import { ParserRuleContext } from "antlr4ts/ParserRuleContext";
import { ParserATNSimulator } from "antlr4ts/atn/ParserATNSimulator";
import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener";
import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor";
import { RecognitionException } from "antlr4ts/RecognitionException";
import { RuleContext } from "antlr4ts/RuleContext";
//import { RuleVersion } from "antlr4ts/RuleVersion";
import { TerminalNode } from "antlr4ts/tree/TerminalNode";
import { Token } from "antlr4ts/Token";
import { TokenStream } from "antlr4ts/TokenStream";
import { Vocabulary } from "antlr4ts/Vocabulary";
import { VocabularyImpl } from "antlr4ts/VocabularyImpl";

import * as Utils from "antlr4ts/misc/Utils";

import { CymbolListener } from "./CymbolListener";
import { CymbolVisitor } from "./CymbolVisitor";


export class CymbolParser extends Parser {
	public static readonly T__0 = 1;
	public static readonly T__1 = 2;
	public static readonly T__2 = 3;
	public static readonly T__3 = 4;
	public static readonly T__4 = 5;
	public static readonly T__5 = 6;
	public static readonly T__6 = 7;
	public static readonly ID = 8;
	public static readonly INT = 9;
	public static readonly WS = 10;
	public static readonly SL_COMMENT = 11;
	public static readonly RULE_decl = 0;
	public static readonly RULE_varDeclaration = 1;
	public static readonly RULE_type = 2;
	public static readonly RULE_expreession = 3;
	public static readonly RULE_primary = 4;
	// tslint:disable:no-trailing-whitespace
	public static readonly ruleNames: string[] = [
		"decl", "varDeclaration", "type", "expreession", "primary",
	];

	private static readonly _LITERAL_NAMES: Array<string | undefined> = [
		undefined, "'='", "';'", "'float'", "'int'", "'+'", "'('", "')'",
	];
	private static readonly _SYMBOLIC_NAMES: Array<string | undefined> = [
		undefined, undefined, undefined, undefined, undefined, undefined, undefined, 
		undefined, "ID", "INT", "WS", "SL_COMMENT",
	];
	public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(CymbolParser._LITERAL_NAMES, CymbolParser._SYMBOLIC_NAMES, []);

	// @Override
	// @NotNull
	public get vocabulary(): Vocabulary {
		return CymbolParser.VOCABULARY;
	}
	// tslint:enable:no-trailing-whitespace

	// @Override
	public get grammarFileName(): string { return "Cymbol.g"; }

	// @Override
	public get ruleNames(): string[] { return CymbolParser.ruleNames; }

	// @Override
	public get serializedATN(): string { return CymbolParser._serializedATN; }

	protected createFailedPredicateException(predicate?: string, message?: string): FailedPredicateException {
		return new FailedPredicateException(this, predicate, message);
	}

	constructor(input: TokenStream) {
		super(input);
		this._interp = new ParserATNSimulator(CymbolParser._ATN, this);
	}
	// @RuleVersion(0)
	public decl(): DeclContext {
		let _localctx: DeclContext = new DeclContext(this._ctx, this.state);
		this.enterRule(_localctx, 0, CymbolParser.RULE_decl);
		let _la: number;
		try {
			this.enterOuterAlt(_localctx, 1);
			{
			this.state = 13;
			this._errHandler.sync(this);
			_la = this._input.LA(1);
			while (_la === CymbolParser.T__2 || _la === CymbolParser.T__3) {
				{
				{
				this.state = 10;
				this.varDeclaration();
				}
				}
				this.state = 15;
				this._errHandler.sync(this);
				_la = this._input.LA(1);
			}
			}
		}
		catch (re) {
			if (re instanceof RecognitionException) {
				_localctx.exception = re;
				this._errHandler.reportError(this, re);
				this._errHandler.recover(this, re);
			} else {
				throw re;
			}
		}
		finally {
			this.exitRule();
		}
		return _localctx;
	}
	// @RuleVersion(0)
	public varDeclaration(): VarDeclarationContext {
		let _localctx: VarDeclarationContext = new VarDeclarationContext(this._ctx, this.state);
		this.enterRule(_localctx, 2, CymbolParser.RULE_varDeclaration);
		let _la: number;
		try {
			this.enterOuterAlt(_localctx, 1);
			{
			this.state = 16;
			this.type();
			this.state = 17;
			this.match(CymbolParser.ID);
			this.state = 20;
			this._errHandler.sync(this);
			_la = this._input.LA(1);
			if (_la === CymbolParser.T__0) {
				{
				this.state = 18;
				this.match(CymbolParser.T__0);
				this.state = 19;
				this.expreession();
				}
			}

			this.state = 22;
			this.match(CymbolParser.T__1);
			}
		}
		catch (re) {
			if (re instanceof RecognitionException) {
				_localctx.exception = re;
				this._errHandler.reportError(this, re);
				this._errHandler.recover(this, re);
			} else {
				throw re;
			}
		}
		finally {
			this.exitRule();
		}
		return _localctx;
	}
	// @RuleVersion(0)
	public type(): TypeContext {
		let _localctx: TypeContext = new TypeContext(this._ctx, this.state);
		this.enterRule(_localctx, 4, CymbolParser.RULE_type);
		let _la: number;
		try {
			this.enterOuterAlt(_localctx, 1);
			{
			this.state = 24;
			_la = this._input.LA(1);
			if (!(_la === CymbolParser.T__2 || _la === CymbolParser.T__3)) {
			this._errHandler.recoverInline(this);
			} else {
				if (this._input.LA(1) === Token.EOF) {
					this.matchedEOF = true;
				}

				this._errHandler.reportMatch(this);
				this.consume();
			}
			}
		}
		catch (re) {
			if (re instanceof RecognitionException) {
				_localctx.exception = re;
				this._errHandler.reportError(this, re);
				this._errHandler.recover(this, re);
			} else {
				throw re;
			}
		}
		finally {
			this.exitRule();
		}
		return _localctx;
	}
	// @RuleVersion(0)
	public expreession(): ExpreessionContext {
		let _localctx: ExpreessionContext = new ExpreessionContext(this._ctx, this.state);
		this.enterRule(_localctx, 6, CymbolParser.RULE_expreession);
		let _la: number;
		try {
			this.enterOuterAlt(_localctx, 1);
			{
			this.state = 26;
			this.primary();
			this.state = 31;
			this._errHandler.sync(this);
			_la = this._input.LA(1);
			while (_la === CymbolParser.T__4) {
				{
				{
				this.state = 27;
				this.match(CymbolParser.T__4);
				this.state = 28;
				this.primary();
				}
				}
				this.state = 33;
				this._errHandler.sync(this);
				_la = this._input.LA(1);
			}
			}
		}
		catch (re) {
			if (re instanceof RecognitionException) {
				_localctx.exception = re;
				this._errHandler.reportError(this, re);
				this._errHandler.recover(this, re);
			} else {
				throw re;
			}
		}
		finally {
			this.exitRule();
		}
		return _localctx;
	}
	// @RuleVersion(0)
	public primary(): PrimaryContext {
		let _localctx: PrimaryContext = new PrimaryContext(this._ctx, this.state);
		this.enterRule(_localctx, 8, CymbolParser.RULE_primary);
		try {
			this.state = 40;
			this._errHandler.sync(this);
			switch (this._input.LA(1)) {
			case CymbolParser.INT:
				this.enterOuterAlt(_localctx, 1);
				{
				this.state = 34;
				this.match(CymbolParser.INT);
				}
				break;
			case CymbolParser.ID:
				this.enterOuterAlt(_localctx, 2);
				{
				this.state = 35;
				this.match(CymbolParser.ID);
				}
				break;
			case CymbolParser.T__5:
				this.enterOuterAlt(_localctx, 3);
				{
				this.state = 36;
				this.match(CymbolParser.T__5);
				this.state = 37;
				this.expreession();
				this.state = 38;
				this.match(CymbolParser.T__6);
				}
				break;
			default:
				throw new NoViableAltException(this);
			}
		}
		catch (re) {
			if (re instanceof RecognitionException) {
				_localctx.exception = re;
				this._errHandler.reportError(this, re);
				this._errHandler.recover(this, re);
			} else {
				throw re;
			}
		}
		finally {
			this.exitRule();
		}
		return _localctx;
	}

	public static readonly _serializedATN: string =
		"\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x03\r-\x04\x02\t" +
		"\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x03\x02\x07" +
		"\x02\x0E\n\x02\f\x02\x0E\x02\x11\v\x02\x03\x03\x03\x03\x03\x03\x03\x03" +
		"\x05\x03\x17\n\x03\x03\x03\x03\x03\x03\x04\x03\x04\x03\x05\x03\x05\x03" +
		"\x05\x07\x05 \n\x05\f\x05\x0E\x05#\v\x05\x03\x06\x03\x06\x03\x06\x03\x06" +
		"\x03\x06\x03\x06\x05\x06+\n\x06\x03\x06\x02\x02\x02\x07\x02\x02\x04\x02" +
		"\x06\x02\b\x02\n\x02\x02\x03\x03\x02\x05\x06\x02,\x02\x0F\x03\x02\x02" +
		"\x02\x04\x12\x03\x02\x02\x02\x06\x1A\x03\x02\x02\x02\b\x1C\x03\x02\x02" +
		"\x02\n*\x03\x02\x02\x02\f\x0E\x05\x04\x03\x02\r\f\x03\x02\x02\x02\x0E" +
		"\x11\x03\x02\x02\x02\x0F\r\x03\x02\x02\x02\x0F\x10\x03\x02\x02\x02\x10" +
		"\x03\x03\x02\x02\x02\x11\x0F\x03\x02\x02\x02\x12\x13\x05\x06\x04\x02\x13" +
		"\x16\x07\n\x02\x02\x14\x15\x07\x03\x02\x02\x15\x17\x05\b\x05\x02\x16\x14" +
		"\x03\x02\x02\x02\x16\x17\x03\x02\x02\x02\x17\x18\x03\x02\x02\x02\x18\x19" +
		"\x07\x04\x02\x02\x19\x05\x03\x02\x02\x02\x1A\x1B\t\x02\x02\x02\x1B\x07" +
		"\x03\x02\x02\x02\x1C!\x05\n\x06\x02\x1D\x1E\x07\x07\x02\x02\x1E \x05\n" +
		"\x06\x02\x1F\x1D\x03\x02\x02\x02 #\x03\x02\x02\x02!\x1F\x03\x02\x02\x02" +
		"!\"\x03\x02\x02\x02\"\t\x03\x02\x02\x02#!\x03\x02\x02\x02$+\x07\v\x02" +
		"\x02%+\x07\n\x02\x02&\'\x07\b\x02\x02\'(\x05\b\x05\x02()\x07\t\x02\x02" +
		")+\x03\x02\x02\x02*$\x03\x02\x02\x02*%\x03\x02\x02\x02*&\x03\x02\x02\x02" +
		"+\v\x03\x02\x02\x02\x06\x0F\x16!*";
	public static __ATN: ATN;
	public static get _ATN(): ATN {
		if (!CymbolParser.__ATN) {
			CymbolParser.__ATN = new ATNDeserializer().deserialize(Utils.toCharArray(CymbolParser._serializedATN));
		}

		return CymbolParser.__ATN;
	}

}

export class DeclContext extends ParserRuleContext {
	public varDeclaration(): VarDeclarationContext[];
	public varDeclaration(i: number): VarDeclarationContext;
	public varDeclaration(i?: number): VarDeclarationContext | VarDeclarationContext[] {
		if (i === undefined) {
			return this.getRuleContexts(VarDeclarationContext);
		} else {
			return this.getRuleContext(i, VarDeclarationContext);
		}
	}
	constructor(parent: ParserRuleContext | undefined, invokingState: number) {
		super(parent, invokingState);
	}
	// @Override
	public get ruleIndex(): number { return CymbolParser.RULE_decl; }
	// @Override
	public enterRule(listener: CymbolListener): void {
		if (listener.enterDecl) {
			listener.enterDecl(this);
		}
	}
	// @Override
	public exitRule(listener: CymbolListener): void {
		if (listener.exitDecl) {
			listener.exitDecl(this);
		}
	}
	// @Override
	public accept<Result>(visitor: CymbolVisitor<Result>): Result {
		if (visitor.visitDecl) {
			return visitor.visitDecl(this);
		} else {
			return visitor.visitChildren(this);
		}
	}
}


export class VarDeclarationContext extends ParserRuleContext {
	public type(): TypeContext {
		return this.getRuleContext(0, TypeContext);
	}
	public ID(): TerminalNode { return this.getToken(CymbolParser.ID, 0); }
	public expreession(): ExpreessionContext | undefined {
		return this.tryGetRuleContext(0, ExpreessionContext);
	}
	constructor(parent: ParserRuleContext | undefined, invokingState: number) {
		super(parent, invokingState);
	}
	// @Override
	public get ruleIndex(): number { return CymbolParser.RULE_varDeclaration; }
	// @Override
	public enterRule(listener: CymbolListener): void {
		if (listener.enterVarDeclaration) {
			listener.enterVarDeclaration(this);
		}
	}
	// @Override
	public exitRule(listener: CymbolListener): void {
		if (listener.exitVarDeclaration) {
			listener.exitVarDeclaration(this);
		}
	}
	// @Override
	public accept<Result>(visitor: CymbolVisitor<Result>): Result {
		if (visitor.visitVarDeclaration) {
			return visitor.visitVarDeclaration(this);
		} else {
			return visitor.visitChildren(this);
		}
	}
}


export class TypeContext extends ParserRuleContext {
	constructor(parent: ParserRuleContext | undefined, invokingState: number) {
		super(parent, invokingState);
	}
	// @Override
	public get ruleIndex(): number { return CymbolParser.RULE_type; }
	// @Override
	public enterRule(listener: CymbolListener): void {
		if (listener.enterType) {
			listener.enterType(this);
		}
	}
	// @Override
	public exitRule(listener: CymbolListener): void {
		if (listener.exitType) {
			listener.exitType(this);
		}
	}
	// @Override
	public accept<Result>(visitor: CymbolVisitor<Result>): Result {
		if (visitor.visitType) {
			return visitor.visitType(this);
		} else {
			return visitor.visitChildren(this);
		}
	}
}


export class ExpreessionContext extends ParserRuleContext {
	public primary(): PrimaryContext[];
	public primary(i: number): PrimaryContext;
	public primary(i?: number): PrimaryContext | PrimaryContext[] {
		if (i === undefined) {
			return this.getRuleContexts(PrimaryContext);
		} else {
			return this.getRuleContext(i, PrimaryContext);
		}
	}
	constructor(parent: ParserRuleContext | undefined, invokingState: number) {
		super(parent, invokingState);
	}
	// @Override
	public get ruleIndex(): number { return CymbolParser.RULE_expreession; }
	// @Override
	public enterRule(listener: CymbolListener): void {
		if (listener.enterExpreession) {
			listener.enterExpreession(this);
		}
	}
	// @Override
	public exitRule(listener: CymbolListener): void {
		if (listener.exitExpreession) {
			listener.exitExpreession(this);
		}
	}
	// @Override
	public accept<Result>(visitor: CymbolVisitor<Result>): Result {
		if (visitor.visitExpreession) {
			return visitor.visitExpreession(this);
		} else {
			return visitor.visitChildren(this);
		}
	}
}


export class PrimaryContext extends ParserRuleContext {
	public INT(): TerminalNode | undefined { return this.tryGetToken(CymbolParser.INT, 0); }
	public ID(): TerminalNode | undefined { return this.tryGetToken(CymbolParser.ID, 0); }
	public expreession(): ExpreessionContext | undefined {
		return this.tryGetRuleContext(0, ExpreessionContext);
	}
	constructor(parent: ParserRuleContext | undefined, invokingState: number) {
		super(parent, invokingState);
	}
	// @Override
	public get ruleIndex(): number { return CymbolParser.RULE_primary; }
	// @Override
	public enterRule(listener: CymbolListener): void {
		if (listener.enterPrimary) {
			listener.enterPrimary(this);
		}
	}
	// @Override
	public exitRule(listener: CymbolListener): void {
		if (listener.exitPrimary) {
			listener.exitPrimary(this);
		}
	}
	// @Override
	public accept<Result>(visitor: CymbolVisitor<Result>): Result {
		if (visitor.visitPrimary) {
			return visitor.visitPrimary(this);
		} else {
			return visitor.visitChildren(this);
		}
	}
}


